package com.xiaoxiong.mami.utils;


import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 
 * 日期工具类
 * 
 * @author zcg<br/>
 * @version 1.0<br/>
 * @email: zcg@suntektech.com<br/>
 * @datetime: 2012-11-19<br/>
 */
public class DateUtils {

	private static char DAY_DELIMITER = '-';
	public static int YEAR = Calendar.YEAR;
	public static int MONTH = Calendar.MONDAY;
	public static int DAY = Calendar.DAY_OF_MONTH;
	public static int HOUR = Calendar.HOUR_OF_DAY;
	public static int MINUTE = Calendar.MINUTE;
	public static int SECOND = Calendar.SECOND;

	/**
	 * 年月日 时间格式
	 */
	public static final String FORMAT1 = "yyyy-MM-dd";

	/**
	 * 年月日时分秒 时间格式
	 */
	public static final String FORMAT2 = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 年月日时分秒 时间格式
	 */
	public static final String FORMAT3 = "yyyyMMddHHmmss";

	/**
	 * 年月日时分秒 时间格式
	 */
	public static final String FORMAT4 = "HHmmss";

	/**
	 * 年月日时分秒 时间格式
	 */
	public static final String FORMAT5 = "yyMMddHHmmss";

	/**
	 * 年月日时分秒 时间格式
	 */
	public static final String FORMAT6 = "HH:mm:ss";

	/**
	 * 时分时间格式
	 */
	public static final String FORMAT7 = "HH:mm";

	/**
	 * 年月日时分时间格式
	 */
	public static final String FORMAT8 = "yyyyMMddHHmm";

	/**
	 * 获取当前日期 yyyy-MM-dd
	 * 
	 * @return
	 */
	public static String getCurrentDate() {
		DateFormat dateFormat = new SimpleDateFormat(FORMAT1);
		return dateFormat.format(new Date());
	}

	/**
	 * 获取当前时间 yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static String getCurrentTime() {
		DateFormat dateFormat = new SimpleDateFormat(FORMAT2);
		return dateFormat.format(new Date());
	}

	/**
	 * 获取当前时间 yyyyMMddHHmmss
	 * 
	 * @return
	 */
	public static String getCurrentTime3() {
		DateFormat dateFormat = new SimpleDateFormat(FORMAT3);
		return dateFormat.format(new Date());
	}

	/**
	 * 获取当前时间 HHmmss
	 * 
	 * @return
	 */
	public static String getCurrentTime4() {
		DateFormat dateFormat = new SimpleDateFormat(FORMAT4);
		return dateFormat.format(new Date());
	}

	/**
	 * 获取当前时间 HH:mm:ss
	 * 
	 * @return
	 */
	public static String getCurrentTime6() {
		DateFormat dateFormat = new SimpleDateFormat(FORMAT6);
		return dateFormat.format(new Date());
	}

	/**
	 * 当前utc时间
	 */
	public static String getCurrentTime5() {
		Date l_datetime = new Date();
		DateFormat formatter = new SimpleDateFormat(FORMAT5);
		String date = formatter.format(l_datetime);
		return date;
	}

	/**
	 * 当前时间
	 */
	public static String getCurrentUtcTime(Date date) {
		DateFormat formatter = new SimpleDateFormat(FORMAT5);
		String l_utc_date = formatter.format(date);
		return l_utc_date;
	}

	/**
	 * 获取当前时间 yyyyMMddHHmm
	 * 
	 * @return
	 */
	public static String getCurrentTime8() {
		DateFormat dateFormat = new SimpleDateFormat(FORMAT8);
		return dateFormat.format(new Date());
	}

	/**
	 * 获取FORMAT1格式的字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String getDate(Date date) {
		DateFormat dateFormat = new SimpleDateFormat(FORMAT1);
		return dateFormat.format(date);
	}

	/**
	 * 获取FORMAT2格式的字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String getTime(Date date) {
		DateFormat dateFormat = new SimpleDateFormat(FORMAT2);
		return dateFormat.format(date);
	}

	/**
	 * 根据日期字符串获取java.util.Date对象
	 * 
	 * @param format
	 *            日期格式
	 * @param dateStr
	 *            字符串日期
	 * @return java.util.Date对象
	 */
	public static Date toUtilDate(String format, String dateStr) {
		DateFormat dateFormat = new SimpleDateFormat(format);
		Date date = null;
		try {
			date = dateFormat.parse(dateStr);
		} catch (ParseException e) {
		}
		return date;
	}

	/**
	 * 根据日期字符串获取java.sql.Date对象
	 * 
	 * @param format
	 *            日期格式
	 * @param dateStr
	 *            字符串日期
	 * @return java.sql.Date对象
	 */
	public static java.sql.Date toSqlDate(String format, String dateStr) {
		java.sql.Date date = new java.sql.Date(toUtilDate(format, dateStr)
				.getTime());
		return date;
	}

	/**
	 * 根据java.util.Date对象得到java.sql.Date对象
	 * 
	 * @param date
	 * @return
	 */
	public static java.sql.Date toSqlDate(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String time = sdf.format(date);
		return toSqlDate("yyyy-MM-dd", time);
	}

	/**
	 * 在指定的日期中按某个时间类型添加指定步长
	 * 
	 * @param datetime
	 *            YYYY-MM-DD HH:MM:SS
	 * @param type
	 *            YEAR,MONTH,DAY,HOUR,MINUTE,SECOND
	 * @param step
	 *            步长 可以是整数或负数
	 * @return 改变后的日期时间 YYYY-MM-DD HH:MM:SS
	 */
	public static String getPreDateTime(String datetime, int type, int step) {

		Calendar calendar = new GregorianCalendar(Integer.parseInt(datetime
				.substring(0, 4)),
				Integer.parseInt(datetime.substring(5, 7)) - 1,
				Integer.parseInt(datetime.substring(8, 10)),
				Integer.parseInt(datetime.substring(11, 13)),
				Integer.parseInt(datetime.substring(14, 16)),
				Integer.parseInt(datetime.substring(17, 19)));
		calendar.add(type, step);
		return getDateTime(calendar);
	}

	/**
	 * 根据字符串类型取得日期类型
	 * 
	 * @param datetime
	 *            String YYYY-MM-DD HH:MM:SS
	 * @return Calendar
	 */
	public static Calendar getCalendar(String datetime) {
		return new GregorianCalendar(
				Integer.parseInt(datetime.substring(0, 4)),
				Integer.parseInt(datetime.substring(5, 7)) - 1,
				Integer.parseInt(datetime.substring(8, 10)),
				Integer.parseInt(datetime.substring(11, 13)),
				Integer.parseInt(datetime.substring(14, 16)),
				Integer.parseInt(datetime.substring(17, 19)));
	}

	/**
	 * 在指定的日期中按某个时间类型添加指定步长
	 * 
	 *            YYYY-MM-DD HH:MM:SS
	 * @param type
	 *            YEAR,MONTH,DAY,HOUR,MINUTE,SECOND
	 * @param step
	 *            步长 可以是整数或负数
	 * @return 改变后的日期时间 YYYY-MM-DD
	 */
	public static String getPreDate(String date, int type, int step) {
		Calendar calendar = new GregorianCalendar(Integer.parseInt(date
				.substring(0, 4)), Integer.parseInt(date.substring(5, 7)) - 1,
				Integer.parseInt(date.substring(8, 10)), 0, 0, 0);
		calendar.add(type, step);
		return getDateTime(calendar).substring(0, 10);
	}

	/**
	 * 在指定的日期中按某个时间类型添加指定步长
	 * 
	 * @param datetime
	 *            YYYY-MM-DD HH:MM:SS
	 * @param step
	 *            步长 可以是整数或负数
	 * @return 改变后的日期时间YYYY-MM-DD HH:MM:SS
	 */
	public static String getPreDate(String datetime, int step) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar c = new GregorianCalendar(Integer.parseInt(datetime.substring(
				0, 4)), Integer.parseInt(datetime.substring(5, 7)) - 1,
				Integer.parseInt(datetime.substring(8, 10)),
				Integer.parseInt(datetime.substring(11, 13)),
				Integer.parseInt(datetime.substring(14, 16)),
				Integer.parseInt(datetime.substring(17, 19)));
		c.add(Calendar.DATE, step);
		return sdf.format(c.getTime());
	}

	/**
	 * 取得当前的日期时间
	 * 
	 * @return YYYYMMDDHHMMDD
	 */
	public static String getDateTimeNoDelim() {

		return getDateTimeNoDelim(new GregorianCalendar());
	}

	/**
	 * 根据日历返回日期时间
	 * 
	 * @param calendar
	 *            日历
	 * @return YYYYMMDDHHMMDD
	 */
	@SuppressWarnings("webapps-access")
	private static String getDateTimeNoDelim(Calendar calendar) {
		StringBuffer buf = new StringBuffer("");

		buf.append(calendar.get(calendar.YEAR));
		buf.append(calendar.get(calendar.MONTH) + 1 > 9 ? calendar
				.get(calendar.MONTH) + 1 + "" : "0"
				+ (calendar.get(calendar.MONTH) + 1));
		buf.append(calendar.get(calendar.DAY_OF_MONTH) > 9 ? calendar
				.get(calendar.DAY_OF_MONTH) + "" : "0"
				+ calendar.get(calendar.DAY_OF_MONTH));
		buf.append(calendar.get(calendar.HOUR_OF_DAY) > 9 ? calendar
				.get(calendar.HOUR_OF_DAY) + "" : "0"
				+ calendar.get(calendar.HOUR_OF_DAY));
		buf.append(calendar.get(calendar.MINUTE) > 9 ? calendar
				.get(calendar.MINUTE) + "" : "0"
				+ calendar.get(calendar.MINUTE));
		buf.append(calendar.get(calendar.SECOND) > 9 ? calendar
				.get(calendar.SECOND) + "" : "0"
				+ calendar.get(calendar.SECOND));
		return buf.toString();
	}

	/**
	 * 根据日历返回日期时间
	 * 
	 * @param calendar
	 *            日历
	 * @return YYYY-MM-DD HH:MM:DD
	 */
	private static String getDateTime(Calendar calendar) {
		StringBuffer buf = new StringBuffer("");

		buf.append(calendar.get(Calendar.YEAR));
		buf.append(DAY_DELIMITER);
		buf.append(calendar.get(Calendar.MONTH) + 1 > 9 ? calendar
				.get(Calendar.MONTH) + 1 + "" : "0"
				+ (calendar.get(Calendar.MONTH) + 1));
		buf.append(DAY_DELIMITER);
		buf.append(calendar.get(Calendar.DAY_OF_MONTH) > 9 ? calendar
				.get(Calendar.DAY_OF_MONTH) + "" : "0"
				+ calendar.get(Calendar.DAY_OF_MONTH));
		buf.append(" ");
		buf.append(calendar.get(Calendar.HOUR_OF_DAY) > 9 ? calendar
				.get(Calendar.HOUR_OF_DAY) + "" : "0"
				+ calendar.get(Calendar.HOUR_OF_DAY));
		buf.append(":");
		buf.append(calendar.get(Calendar.MINUTE) > 9 ? calendar
				.get(Calendar.MINUTE) + "" : "0"
				+ calendar.get(Calendar.MINUTE));
		buf.append(":");
		buf.append(calendar.get(Calendar.SECOND) > 9 ? calendar
				.get(Calendar.SECOND) + "" : "0"
				+ calendar.get(Calendar.SECOND));
		return buf.toString();
	}

	/**
	 * 获得昨天的时间,yyyy-MM-dd
	 * 
	 * @return
	 */
	public static String getPreDate() {
		Calendar now = Calendar.getInstance();
		now.add(Calendar.DATE, -1);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date = now.getTime();
		String before = sdf.format(date);
		return before;
	}
	
	/**
	 * 获得昨天的时间,yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static Date getNextDate() {
		Calendar now = Calendar.getInstance();
		now.add(Calendar.DATE, 1);
		Date date = now.getTime();
		return date;
	}
	
	/**
	 * 获得昨天的时间,yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static String formateDate(String formate,Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(formate);
		return sdf.format(date);
	}
	
	/**
	 * 获得昨天的日期时间字符串,yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static String getPreDatetime() {
		Calendar now = Calendar.getInstance();
		now.add(Calendar.DATE, -1);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = now.getTime();
		String before = sdf.format(date);
		return before;
	}

	/**
	 * 获得昨天的结束时刻,YYYY-MM-DD 23:59:59
	 * 
	 * @return
	 */
	public static String getPreLastTime() {
		Calendar now = Calendar.getInstance();
		now.add(Calendar.DATE, -1);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date = now.getTime();
		String before = sdf.format(date);
		return before + " 23:59:59";
	}

	/**
	 * 获得当天的开始时刻,YYYY-MM-DD 00:00:00
	 * 
	 * @return
	 */
	public static String getCurrentFirstTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.format(new Date()) + " 00:00:00";
	}

	/**
	 * 获得当天的结束时刻,YYYY-MM-DD 23:59:59
	 * 
	 * @return
	 */
	public static String getCurrentLastTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.format(new Date()) + " 23:59:59";
	}

	/**
	 * 注意：传入时间字符串和SimpleDateFormat格式一致 获取当前时间的毫秒数
	 * 
	 * @param dateStr
	 * @return
	 * @throws ParseException
	 */
	public static long toDateTime(String dateStr) throws ParseException {
		DateFormat dateFormat = new SimpleDateFormat(FORMAT2);
		return dateFormat.parse(dateStr).getTime();
	}

	/**
	 * 判断传入时间是否晚于当于时间
	 * 
	 * @param dateStr
	 * @return
	 */
	public static boolean afterDateTime(String dateStr) {
		Date paramDate = toUtilDate(FORMAT2, dateStr);
		return paramDate.after(new Date());
	}

	/**
	 * 判断当前日期是否大于最后的限定时间
	 * 
	 * @param lastActiveTime
	 *            最后的活跃时间
	 * @param days
	 *            过期天数
	 * @return true:达到限定时间，false:未达到限定时间
	 */
	public static boolean isAfterLastActiveDate(Date lastActiveTime, int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(lastActiveTime);
		calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR)
				+ days);
		boolean isOver = new Date().after(calendar.getTime());
		return isOver;
	}

	/**
	 * 格式化字符串，解决从MySql中查出来的数据后面多了0的问题
	 * 
	 * @param date
	 * @return
	 */
	public static String formatDate(String dateFormat, String newFormat,
			String date) {
		Date parseDate = toUtilDate(dateFormat, date);
		SimpleDateFormat sdf = new SimpleDateFormat(newFormat);
		return sdf.format(parseDate);
	}
	
	public static long subtractDate(String str, Date date2) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date1;
		long result = (long) 0.0;
		try {
			date1 = df.parse(str);
			result = (date2.getTime() - date1.getTime()) / 1000;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 获取指定日期所在星期的日期列表(周一到周日)
	 * 
	 * @param datestr
	 *            为 yyyy-MM-dd 格式日期字符串 例：2015-01-01
	 * @return
	 */
	public static List<String> makeWeekdays(String datestr) {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		Date date = null;
		try {
			date = sdf.parse(datestr);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}

		return makeWeekdays(date);
	}

	/**
	 * 获取指定日期所在星期的日期列表(周一到周日)
	 * 
	 * @param date
	 * @return
	 */
	public static List<String> makeWeekdays(Date date) {
		
		if (date == null) {
			return null;
		}

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		// 定义星期一为一周的第一天
		final int FIRST_DAY = Calendar.MONDAY;

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		// 循环找到星期一那天的日期
		while (calendar.get(Calendar.DAY_OF_WEEK) != FIRST_DAY) {
			calendar.add(Calendar.DATE, -1);
		}

		List<String> weekdays = new ArrayList<String>(7);
		for (int i = 0; i < 7; i++) {
			String day = sdf.format(calendar.getTime());
			weekdays.add(day);
			// 计算下一天
			calendar.add(Calendar.DATE, 1);
		}

		return weekdays;
	}
	
	/**
	 * 比较两个日期是否在同一个星期（周一到周日为一个星期）
	 * 
	 * @param date1  为 yyyy-MM-dd 格式日期字符串 例：2015-01-01
	 * @param date2  为 yyyy-MM-dd 格式日期字符串 例：2015-01-02
	 * @return
	 */
	public static boolean isSameWeek(String date1, String date2){
		
		boolean flag = false;
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		// 非空判断
		if(!StringUtils.isEmpty(date1) && !StringUtils.isEmpty(date2) ){
			//检验格式
			try {
				sdf.parse(date1);
				sdf.parse(date2);
			} catch (ParseException e) {
				e.printStackTrace();
				return flag;
			}
		}else{
			return flag;
		}
		
		List<String> weekdays = makeWeekdays(date1);
		
		for (String day : weekdays) {
			if(day.equals(date2)){
				flag = true;
				return flag;
			}
		}
		
		return flag;
	}
	
	/**
	 * 比较两个日期是否同一个月
	 * 
	 * @param date1  为 yyyy-MM-dd 格式日期字符串 例：2015-01-01
	 * @param date2  为 yyyy-MM-dd 格式日期字符串 例：2015-01-02
	 * @return
	 */
	public static boolean isSameMonth(String date1, String date2){
		
		boolean flag = false;
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		// 非空判断
		if(!StringUtils.isEmpty(date1) && !StringUtils.isEmpty(date2) ){
			//检验格式
			try {
				sdf.parse(date1);
				sdf.parse(date2);
			} catch (ParseException e) {
				e.printStackTrace();
				return flag;
			}
		}else{
			return flag;
		}
		
		if(date1.substring(0, 7).equals(date2.substring(0, 7))){
			flag = true;
		}
		
		return flag;
	}
	
	/**
	 * 比较两个日期是否同一个月
	 * 
	 * @param date1  
	 * @param date2 
	 * @return
	 */
	public static boolean isSameMonth(Date date1, Date date2){
		
		boolean flag = false;
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		
		String date1str = sdf.format(date1);
		String date2str = sdf.format(date2);
		
		
		if(date1str.equals(date2str)){
			flag = true;
		}
		
		return flag;
	}
	
	/**
	 * 
	 * @Description:根据日期，获取时间字符串   模式： 2013 201307 20130707 1373522078029
	 * @param date
	 * @param type
	 * 
	 */
	public static String getDateSerilalNum(Date date, int type) {
		String str = "";
		SimpleDateFormat bartDateFormat = null;
		if (type == 1) {

		} else if (type == 2) {
			bartDateFormat = new SimpleDateFormat("yyyy");
			str = bartDateFormat.format(date);
		} else if (type == 3) {
			bartDateFormat = new SimpleDateFormat("yyyyMM");
			str = bartDateFormat.format(date);
		} else if (type == 4) {
			bartDateFormat = new SimpleDateFormat("yyyyMMdd");
			str = bartDateFormat.format(date);
		} else if (type == 5) {
			bartDateFormat = new SimpleDateFormat("yyyyMMddHH");
			str = bartDateFormat.format(date);
		} else if (type == 6) {
			bartDateFormat = new SimpleDateFormat("yyyyMMddHHmm");
			str = bartDateFormat.format(date);
		} else if (type == 7) {
			str = date.getTime() + "";
		}
		return str;
	}
	
	/** 
	 * 比较两个日期之间的大小 
	 *  
	 * @param d1 
	 * @param d2 
	 * @return 前者大于后者返回true 反之false 
	 */  
	public static boolean compareDate(Date d1, Date d2) {  
	    Calendar c1 = Calendar.getInstance();  
	    Calendar c2 = Calendar.getInstance();  
	    c1.setTime(d1);  
	    c2.setTime(d2);  
	  
	    int result = c1.compareTo(c2);  
	    if (result >= 0)  
	        return true;  
	    else  
	        return false;  
	}

	public static long strToTimeStamp(String time){
		SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		try {
			date = format.parse(time);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date.getTime();
	}



}
